﻿using CaseManagerLibrary.DB.SQLite;
using CaseManagerLibrary.Http;
using CaseManagerLibrary.Models;
using Newtonsoft.Json;
using PSDClientService.SystemSettings;
using PSDLib.Models;
using System;
using System.Collections.Generic;
using System.Data.SQLite;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PSDClientService.Download
{
    public class LocalDataManager
    {
        private Queue<dl_files> fileBuffer = new Queue<dl_files>();

        private Thread fileThread = null;
        private Thread syncThread = null;

        private DownloadContext context;

        private SQLiteHelper sqlite;
        public bool EnableLocalStorage { get; private set; }

        private static object lock_sync = new object();
        public LocalDataManager(DownloadContext ctx)
        {
            context = ctx;
        }

        public bool Init()
        {
            string localDataFile = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "PSD", "Data", "localdata.db");

            EnableLocalStorage = System.IO.File.Exists(localDataFile);

            if (EnableLocalStorage)
            {
                sqlite = new SQLiteHelper();
                sqlite.FileName = localDataFile;

                fileThread = new Thread(new ThreadStart(HandleFile));
                fileThread.Start();

                syncThread = new Thread(new ThreadStart(SyncToServer));
                syncThread.Start();

            }

            return EnableLocalStorage;
        }

        public void Dispose()
        {
            EnableLocalStorage = false;

            try
            {
                if (fileThread != null)
                {
                    fileThread.Abort();
                }
            }
            catch { }

            try
            {
                if (syncThread != null)
                {
                    syncThread.Abort();
                }
            }
            catch { }
        }

        public void AddFile(dl_files file)
        {
            fileBuffer.Enqueue(file);
        }

        /// <summary>
        /// 将下载结果上传服务器，如果失败则保存本地
        /// </summary>
        private void HandleFile()
        {
            while (context.Running && EnableLocalStorage)
            {
                if (fileBuffer.Count > 0)
                {
                    lock (lock_sync)
                    {
                        var conn = sqlite.Open();

                        while (fileBuffer.Count > 0)
                        {
                            var file = fileBuffer.Dequeue();

                            if (EnableLocalStorage)
                            {
                                SaveToLocal(conn, file);
                            }
                        }

                        if (conn != null)
                        {
                            sqlite.Close(conn);
                        }
                    }
                }

                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// 定期将本地数据同步到服务器
        /// </summary>
        private void SyncToServer()
        {
            while (context.Running && EnableLocalStorage)
            {
                lock (lock_sync)
                {
                    var conn = sqlite.Open();

                    if (conn != null)
                    {
                        try
                        {
                            string sql = "select * from local_files";
                            var list = sqlite.Query<local_files>(conn, sql);

                            foreach (var f in list)
                            {
                                var file = f.To_dl_file();

                                var ret = SaveToServer(file);

                                if (ret.success)
                                {
                                    sql = "delete from local_files where dl_id='" + f.dl_id + "'";
                                    sqlite.Execute(conn, sql);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            context.Logger.Error("LocalDataSyncToServer Error：" + ex.Message);
                        }
                        finally
                        {
                            sqlite.Close(conn);
                        }
                    }
                }

                Thread.Sleep(1000 * 60);
            }
        }

        private void SaveToLocal(SQLiteConnection conn, dl_files file)
        {
            local_files lf = new local_files();
            lf.From_dl_file(file);

            sqlite.Insert<local_files>(conn, lf);
        }

        private HResult SaveToServer(dl_files file)
        {
            var url = "";

            if (file.state == 1)
            {
                url = AppSettings.Setting.API.DownloadSuccess;
            }
            else
            {
                url = AppSettings.Setting.API.DownloadFail;
            }

            var result = HttpHelper.Post<HResult>(url, JsonConvert.SerializeObject(file));

            return result;
        }

    }


}
